package itsm.isperp.module.controller.project;

import itsm.isperp.control.form.table.TreeTable;
import itsm.isperp.framework.collection.tree.ITreeNode;
import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.data.domain.PageResponse;
import itsm.isperp.framework.domain.IUser;
import itsm.isperp.framework.utils.HibernateUUIDGenerator;
import itsm.isperp.framework.web.controller.BaseProcessController;
import itsm.isperp.framework.web.domain.CountQuery;
import itsm.isperp.framework.web.request.JqGridFilter;
import itsm.isperp.framework.web.request.JqGridFilterRule;
import itsm.isperp.framework.web.request.JqGridFilterRuleOp;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.framework.web.response.ResultMessage;
import itsm.isperp.module.dto.project.ProjectDomain;
import itsm.isperp.module.dto.project.ProjectDomain.ProjectDomainType;
import itsm.isperp.module.entity.app.AppCalendarConfig;
import itsm.isperp.module.entity.app.AppDict;
import itsm.isperp.module.entity.project.ProjCostTemplate;
import itsm.isperp.module.entity.project.ProjProject;
import itsm.isperp.module.entity.project.ProjProjectCategory;
import itsm.isperp.module.service.app.AppCalendarConfigService;
import itsm.isperp.module.service.app.AppDictService;
import itsm.isperp.module.service.app.AppRoleService;
import itsm.isperp.module.service.project.ProjCostItemService;
import itsm.isperp.module.service.project.ProjCostTemplateService;
import itsm.isperp.module.service.project.ProjProjectCategoryService;
import itsm.isperp.module.service.project.ProjProjectService;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * 项目管理控制器
 * 
 * @author lizx
 * @date 2013-2-26
 * @version V1.0
 */
@Controller
@RequestMapping("project/project")
public class ProjProjectController extends BaseProcessController<ProjProject> {

  @Autowired
  protected ProjProjectService projProjectService;

  @Autowired
  protected ProjProjectCategoryService projProjectCategoryService;

  @Autowired
  protected AppDictService appDictService;

  @Override
  public ProjProjectService getService() {
    return this.projProjectService;
  }

  @Override
  public String getProceessKey() {
    return "projectProcess";
  }

  @Override
  public String getPageTitle() {
    return "项目管理";
  }

  // --------------项目配置-----------------------------------------
  @RequestMapping("delete")
  @ResponseBody
  @Override
  public ResultMessage delete(String id, HttpServletRequest req) {

    Map<String, Object> map = this.getService().getProjectStageAndStatus(id);
    if (MapUtils.isNotEmpty(map)) {
      Object process_id = map.get("process_id");

      if (map.get("stage") == null || (ProjProjectService.STAGE_UNPUBLICED.equals(map.get("stage").toString()) && process_id != null && process_id.toString() != "") || process_id == null) {
        this.getService().delete(id);
        return ResultMessage.success();
      }
    }

    return ResultMessage.failure("已提交审批项目不能删除");
  }

  private CountQuery getConfigCountQuery() {
    CountQuery cq = createDefaultCountQuery();
    List<AppDict> pStatus = appDictService.findByType("PROJECT_STATUS");
    String  loginUserName=ContextHolder.getLoginUsername();
    AppRoleService appRoleService = ContextHolder.getSpringBean("appRoleService");
    String roleId = appRoleService.getRoleIdByName("项目总监", loginUserName);
    String condition=" manager_id='"+loginUserName+"' or seller_id='"+loginUserName+"' or creator='"+loginUserName+"' or (EXISTS(SELECT 1 FROM proj_project_member WHERE proj_project_id=proj_project.id AND app_user_name='"+loginUserName+"'))";

    if(loginUserName.equals("admin") || StringUtils.isNotEmpty(roleId))
      condition="1=1";
    
    for (AppDict dict : pStatus) {
      cq.addCountFilter(dict.getName(), " (status='" + dict.getName() + "') and ("+condition+")");
    }
    cq.addCountFilter("所有", " 1=1 and ("+condition+")");
    return cq;
  }

  @RequestMapping("configMenu")
  @ResponseBody
  public ITreeNode[] configMenu() {

    CountQuery cq = this.getConfigCountQuery();

    cq.addQueryFilterRule("stage", JqGridFilterRuleOp.ne, ProjProjectService.STAGE_FINISHED);
    return cq.getTreeNodes();
  }

  @RequestMapping("configList")
  @ResponseBody
  public PageResponse<ProjProject> configList(JqGridRequest request, HttpServletRequest req) {
    //request.addFilterRule("stage", JqGridFilterRuleOp.ne, ProjProjectService.STAGE_FINISHED);
    String  loginUserName=ContextHolder.getLoginUsername();
    String condition=" manager_id='"+loginUserName+"' or seller_id='"+loginUserName+"' or creator='"+loginUserName+"' or (EXISTS(SELECT 1 FROM proj_project_member WHERE proj_project_id=proj_project.id AND app_user_name='"+loginUserName+"'))";
    if(loginUserName.equals("admin"))
      condition="1=1";
    AppRoleService appRoleService = ContextHolder.getSpringBean("appRoleService");

    String roleId = appRoleService.getRoleIdByName("项目总监", loginUserName);

    if (!ContextHolder.getLoginUsername().equals("admin") && StringUtils.isEmpty(roleId))
      request.setSearchString(condition);
    CountQuery cq = getConfigCountQuery();
    PageResponse<ProjProject> T = this.getList(cq, request, req);
    return this.getList(cq, request, req);

  }

  @RequestMapping("configCount")
  @ResponseBody
  public Long configCount() {
    String  loginUserName=ContextHolder.getLoginUsername();
    String condition=" manager_id='"+loginUserName+"' or seller_id='"+loginUserName+"' or creator='"+loginUserName+"' or (EXISTS(SELECT 1 FROM proj_project_member WHERE proj_project_id=proj_project.id AND app_user_name='"+loginUserName+"'))";
    if(loginUserName.equals("admin"))
      condition="1=1";
    AppRoleService appRoleService = ContextHolder.getSpringBean("appRoleService");
    String roleId = appRoleService.getRoleIdByName("项目总监", loginUserName);
    JqGridRequest request=new JqGridRequest();
    if (!ContextHolder.getLoginUsername().equals("admin") && StringUtils.isEmpty(roleId))
      request.setSearchString(condition);
    return (long)this.getService().findAll(request).getContent().size();
  }

  // --------------end 项目配置-----------------------------------------

  // --------------项目归档-----------------------------------------

  @RequestMapping("onFileMenu")
  @ResponseBody
  public ITreeNode[] onFileMenu() {
    return this.getOnFileMenuCountQuery().getTreeNodes();
  }

  private CountQuery getOnFileMenuCountQuery() {
    CountQuery cq = createDefaultCountQuery();
    // 设置数据权限域
    cq.setProjectDomain(ProjectDomain.newInstance("id", ProjectDomainType.Management));

    cq.addCountFilter("已过期", true, " stage='" + ProjProjectService.STAGE_PUBLICED + "' AND  (end_date<=CURDATE()) ");
    cq.addCountFilter("一个月内到期", " stage='" + ProjProjectService.STAGE_PUBLICED + "' AND (end_date>=CURDATE() AND DATE_SUB(CURDATE(), INTERVAL -1 MONTH) >= date(end_date))");
    cq.addCountFilter("三个月内到期", " stage='" + ProjProjectService.STAGE_PUBLICED + "' AND (DATE_SUB(CURDATE(), INTERVAL -1 MONTH) < date(end_date) AND  date(end_date)<=  DATE_SUB(CURDATE(), INTERVAL -3 MONTH) )");

    return cq;
  }

  @RequestMapping("onFileList")
  @ResponseBody
  public PageResponse<ProjProject> onFileList(JqGridRequest request, HttpServletRequest req) {
    request.setProjectDomain(ProjectDomain.newInstance("id", ProjectDomainType.Management));
    return this.getList(getOnFileMenuCountQuery(), request, req);

  }

  /**
   * 项目归档管理
   * 
   * @param req
   *            请求数据
   * @return 归档界面
   */
  @RequestMapping("projectOnFileManage")
  public ModelAndView projectOnFileManage(HttpServletRequest req) {
    return this.getModelAndView();
  }

  /**
   * 项目归档编辑
   * 
   * @param req
   *            请求数据
   * @return 项目归档
   */
  @RequestMapping("projectOnFileEdit")
  public ModelAndView projectOnFileEdit(String id, HttpServletRequest req) {
    ModelAndView mv = new ModelAndView("project/project/projectOnFileEdit");

    // 项目基本信息
    ProjProject model = null;

    if (StringUtils.isEmpty(id)) {

      model = new ProjProject();
      model.setId(HibernateUUIDGenerator.generate());
    } else {
      model = this.projProjectService.findOne(id);
    }

    if (StringUtils.isNotEmpty(model.getProjCategoryId())) {
      ProjProjectCategory cate = this.projProjectCategoryService.findOne(model.getProjCategoryId());
      mv.addObject("projectCategoryName", cate.getTreenodeNamePath());
    }

    mv.addObject("projectLevels", appDictService.findByType("PROJECT_LEVEL"));
    mv.addObject("projectTypes", appDictService.findByType("PROJECT_TYPE"));

    mv.addObject("projectStatus", appDictService.findByType("PROJECT_STATUS"));
    mv.addObject("model", model);

    mv.addObject("name", "项目归档");
    return mv;
  }

  /**
   * 快速添加项目
   * 
   * @param id
   *            项目id
   * @param req
   *            http请求
   * @return 快速添加项目页
   */
  @RequestMapping(value = {
    "quickstartEdit" })
  public ModelAndView quickstartEdit(String id, HttpServletRequest req) {
    return getProjectModelAndView(id, getModulePath() + "/quickstartEdit");
  }

  @RequestMapping(value = {
    "step1Edit" })
  public ModelAndView step1Edit(String id, HttpServletRequest req) {
    return getProjectModelAndView(id, getModulePath() + "/step1Edit");
  }

  @RequestMapping(value = {
    "step2Edit" })
  public ModelAndView step2Edit(String id, HttpServletRequest req) {
    return getProjectModelAndView(id, getModulePath() + "/step2Edit");
  }

  private ModelAndView getProjectModelAndView(String id, String view) {
    ModelAndView mv = new ModelAndView(view);
    AppDictService appDictService = ContextHolder.getSpringBean(AppDictService.class);

    String initStatus = appDictService.getInitStatus("PROJECT_STATUS");
    mv.addObject("initStatus", initStatus);
    // 项目基本信息
    ProjProject model = null;
    if (StringUtils.isEmpty(id)) {

      model = new ProjProject();
      model.setId(HibernateUUIDGenerator.generate());
      IUser user = ContextHolder.getLoginUser();

      model.setManagerId(user.getUsername());
      model.setManagerName(user.getFullname());
      model.setStatus(initStatus);

    } else {
      model = this.projProjectService.findOne(id);
      // if (StringUtils.isNotEmpty(model.getCusCustomerId())) {
      //
      // CusCustomerService cusCustomerService = ContextHolder
      // .getSpringBean("cusCustomerService");
      //
      // mv.addObject("cusCustomerName",
      // cusCustomerService.findOne(model.getCusCustomerId())
      // .getName());
      // }
    }

    AppCalendarConfigService appCalendarConfigService = ContextHolder.getSpringBean("appCalendarConfigService");

    List<AppCalendarConfig> list = appCalendarConfigService.findAll(new JqGridRequest().isPageable(false).setSelectColumns("id", "name"));

    mv.addObject("appCalendars", list);

    mv.addObject("projectLevels", appDictService.findByType("PROJECT_LEVEL"));
    mv.addObject("projectTypes", appDictService.findByType("PROJECT_TYPE"));

    mv.addObject("projectStatus", appDictService.findByType("PROJECT_STATUS"));
    mv.addObject("model", model);

    mv.addObject("name", "快速添加项目");

    return mv;
  }

  @Override
  @RequestMapping(value = {
    "view" })
  public ModelAndView view(String id, HttpServletRequest req) {
    ModelAndView mv = this.getModelAndView();

    // 项目基本信息
    ProjProject model = this.projProjectService.findOne(id);
    AppCalendarConfigService appCalendarConfigService = ContextHolder.getSpringBean("appCalendarConfigService");

    AppCalendarConfig cc = appCalendarConfigService.findOne(model.getAppCalendarConfigId());

    mv.addObject("model", model);
    if (cc != null) {
      mv.addObject("appCalendarConfigName", cc.getName());
    }

    return mv;
  }

  /**
   * 项目服务范围
   * 
   * @param projectId
   *            项目id
   * @param req
   *            http请求
   * @return 项目服务范围界面
   */
  @RequestMapping("scopeOfService")
  public ModelAndView scopeOfService(String projectId, HttpServletRequest req) {

    ModelAndView mv = new ModelAndView("project/project/scopeOfService");
    mv.addObject("projectId", projectId);

    return mv;
  }

  /**
   * 项目人员编辑界面
   * 
   * @param projectId
   *            项目id
   * @param req
   *            http请求
   * @return 项目人力编辑界面
   */
  @RequestMapping("member")
  public ModelAndView member(String projectId, HttpServletRequest req) {

    ModelAndView mv = new ModelAndView("project/project/member");
    mv.addObject("projectId", projectId);
    mv.addObject("pageTitle", "项目人员");
    return mv;
  }

  /**
   * 项目计划界面
   * 
   * @param projectId
   *            项目id
   * @param req
   *            http请求
   * @return 项目计划界面
   */
  @RequestMapping("plan")
  public ModelAndView plan(String projectId, HttpServletRequest req) {

    ModelAndView mv = new ModelAndView("project/project/plan");
    mv.addObject("projectId", projectId);
    mv.addObject("pageTitle", "计划任务");
    return mv;
  }

  @RequestMapping("getProjectCost")
  @ResponseBody
  public String getProjectCost(String projectId, String projCostTemplateId) {

    return this.getService().getCostTreeTable(projectId, projCostTemplateId).renderHtml();

  }

  @RequestMapping("getCostAccountingEntryAmount")
  @ResponseBody
  public List<Map<String, Object>> getCostAccountingEntryAmount(String projectId) {

    return this.getService().getCostAccountingEntryAmount(projectId);

  }

  /**
   * 项目预算界面
   * 
   * @param projectId
   *            项目id
   * @param req
   *            http请求
   * @return 预算界面
   */
  @RequestMapping(value = {
      "cost/costAccountingView", "cost/costAccounting" })
  public ModelAndView costAccounting(String projectId, HttpServletRequest req) {

    ModelAndView mv = new ModelAndView("project/cost/costAccountingView");

    String projCostTemplateId = req.getParameter("projCostTemplateId");

    if (StringUtils.isNotEmpty(projCostTemplateId)) {
      TreeTable tt = this.getService().getCostTreeTable(projectId, projCostTemplateId);
      mv.addObject("projCostTemplateId", projCostTemplateId);
      mv.addObject("projectCost", tt.renderHtml());

    } else {

      Map<String, Object> maps = this.getService().findOneToMap(projectId, "proj_cost_template_id", "account");
      if (maps != null && maps.containsKey("proj_cost_template_id")) {

        projCostTemplateId = (String) maps.get("proj_cost_template_id");

        TreeTable tt = this.getService().getCostTreeTable(projectId, projCostTemplateId);

        mv.addObject("projCostTemplateId", projCostTemplateId);
        mv.addObject("account", maps.get("account"));

        mv.addObject("projectCost", tt.renderHtml());

        mv.addObject("projectId", projectId);
        mv.addObject("coseWithAccounting", true);

      }

    }

    return mv;
  }

  /**
   * 项目预算界面
   * 
   * @param projectId
   *            项目id
   * @param req
   *            http请求
   * @return 预算界面
   */
  @RequestMapping("cost")
  public ModelAndView cost(String projectId, HttpServletRequest req) {

    ModelAndView mv = new ModelAndView("project/project/cost");

    String state = req.getParameter("state");
    ProjCostTemplateService tempService = ContextHolder.getSpringBean("projCostTemplateService");

    mv.addObject("projectId", projectId);

    Map<String, Object> maps = this.getService().findOneToMap(projectId, "proj_cost_template_id", "account");

    String projCostTemplateId = "";
    if (maps != null && maps.containsKey("proj_cost_template_id")) {

      projCostTemplateId = (String) maps.get("proj_cost_template_id");

      TreeTable tt = this.getService().getCostTreeTable(projectId, projCostTemplateId);

      mv.addObject("projectCost", tt.renderHtml());
    }
    mv.addObject("projCostTemplateId", projCostTemplateId);
    if ("view".equals(state)) {

      ProjCostTemplate costTemplate = tempService.findOne(projCostTemplateId);

      mv.addObject("costTemplate", costTemplate);
    } else {

      List<ProjCostTemplate> costTemplates = tempService.findTemplates();
      costTemplates.add(0, new ProjCostTemplate());
      mv.addObject("costTemplates", costTemplates);

    }

    mv.addObject("projectId", projectId);
    if (maps != null)
      mv.addObject("account", maps.get("account"));

    mv.addObject("pageTitle", "项目预算");
    mv.addObject("state", state);
    return mv;
  }

  /**
   * 项目质量界面
   * 
   * @param projectId
   *            项目id
   * @param req
   *            http请求
   * @return 项目质量界面
   */
  @RequestMapping("quality")
  public ModelAndView quality(String projectId, HttpServletRequest req) {

    ModelAndView mv = new ModelAndView("project/project/quality");
    mv.addObject("projectId", projectId);
    mv.addObject("pageTitle", "服务协议");
    return mv;
  }

  /**
   * 更新项目的配置描述
   * 
   * @param projectId
   *            项目
   * @param confDescription
   *            配置描述
   * @return 数据结果
   */
  @RequestMapping("updateConfDescription")
  @ResponseBody
  public ResultMessage updateConfDescription(String projectId, String confDescription) {
    this.projProjectService.updateConfDescription(projectId, confDescription);
    return ResultMessage.newInstance(true);

  }

  /**
   * 保存项目预算项
   * 
   * @param projectId
   *            项目Id
   * @param projCostTemplateId
   *            预算模板Id
   * @param amount
   *            金额
   * @return 结果消息
   */
  @RequestMapping("saveProjectCost")
  @ResponseBody
  public ResultMessage saveProjectCost(String projectId, String projCostTemplateId, HttpServletRequest request) {
    // 更新项目关联的预算模板
    this.projProjectService.updateCostTemplateId(projectId, projCostTemplateId);

    @SuppressWarnings("unchecked")
    Enumeration<String> e = request.getParameterNames();

    List<String[]> costAmounts = new ArrayList<>();

    while (e.hasMoreElements()) {
      String ename = e.nextElement();
      if (ename.contains("cost_")) {
        String value = request.getParameter(ename);

        if (StringUtils.isEmpty(value))
          value = "0";

        String treeId = ename.substring(5);
        costAmounts.add(new String[] {
            value, treeId });

      }

    }

    // String[] strArr = amount.split(",");

    // String[] treeNodeArr = treeNodeIds.split(",");

    ProjCostItemService projCostItemService = ContextHolder.getSpringBean("projCostItemService");

    projCostItemService.deleteByProjectId(projectId);

    projCostItemService.batchInsert(costAmounts, projectId, projCostTemplateId);

    return ResultMessage.success();
  }

  /**
   * 项目审批管理界面
   * 
   * @param req
   *            请求数据
   * @return 管理界面
   */
  @RequestMapping("approval")
  public ModelAndView approval(HttpServletRequest req) {
    ModelAndView mv = new ModelAndView("project/project/approval");
    mv.addObject("pageTitle", "项目审批列表");
    return mv;
  }

  /**
   * 结束项目（项目归档时使用）
   * 
   * @param id
   *            项目id
   * @param projCategoryId
   *            项目分类id
   * @return 结果消息
   */
  @RequestMapping("finishProject")
  @ResponseBody
  public ResultMessage finishProject(String id, String projCategoryId) {

    this.getService().updateProjectCategory(id, projCategoryId);

    this.getService().finishProject(id);

    return ResultMessage.success();
  }

}
